package com.wwdx.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wwdx.model.WwdxBookModel;
import com.wwdx.model.WwdxOrderModel;
import com.wwdx.model.WwdxThemeModel;
import com.wwdx.model.dto.PurchaseCordDTO;
import com.wwdx.service.WwdxOrderServiceI;
import com.wwdx.utils.ConstantHolder;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author liguoliang
 * @date 2017/11/5.
 */
@Service
public class WwdxOrderServiceImpl extends BaseServiceImpl<WwdxOrderModel> implements WwdxOrderServiceI {

    @Override
    public Long selectModelCount(WwdxOrderModel model) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(4);
        String hql = "select count(1) from WwdxOrderModel\t" + getParams(model, params);
        return this.count(hql, params);
    }

    private String getParams(WwdxOrderModel model, Map<String, Object> params) {
        StringBuilder sb = new StringBuilder("where 1=1\n");
        Integer status = model.getStatus();
        if (status != null) {
            sb.append("and status=:status\n");
            params.put("status", status);
        }
        Integer type = model.getType();
        if (type != null) {
            sb.append("and type=:type\n");
            params.put("type", type);
        }
        Integer payType = model.getPayType();
        if (payType != null){
            sb.append("and payType=:payType\n");
            params.put("payType", payType);
        }
        String channel = model.getChannel();
        if (StringUtils.isNotBlank(channel)) {
            sb.append("and channel=:channel\n");
            params.put("channel", channel);
        }
        String orderno = model.getOrderno();
        if (StringUtils.isNotBlank(orderno)) {
            sb.append("and orderno=:orderno\n");
            params.put("orderno", orderno);
        }
        return sb.toString();
    }

    @Override
    public List<WwdxOrderModel> selectModelList(WwdxOrderModel model, Integer page, Integer rows) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(4);
        String hql = "from WwdxOrderModel\t" + getParams(model, params) + "\norder by createTime desc";
        return this.excute(find(hql, params, page, rows));
    }

    @Override
    public List<WwdxOrderModel> excute(List<WwdxOrderModel> orderModels) {
        for (WwdxOrderModel wwdxOrderModel : orderModels) {
            //用户名称
            wwdxOrderModel.setMemberName(wwdxPersonalService.getByUnionid(wwdxOrderModel.getUnionid()).getNickname());
            //是否支付
            Integer status = wwdxOrderModel.getStatus();
            wwdxOrderModel.setIsPay(status == 1 ? "已支付" : "未支付");
            //产品类型
            Integer type = wwdxOrderModel.getType();
            Long productId = wwdxOrderModel.getProduct_id();
            switch (type) {
                case ConstantHolder.Constant.THEMETYPE:
                    wwdxOrderModel.setStrType("阅读包");
                    wwdxOrderModel.setProductName(wwdxThemeService.getByThemeId(productId).getTitle());
                    break;
                case ConstantHolder.Constant.BOOKTYPE:
                case ConstantHolder.Constant.SMALLBOOKTYPE:
                    wwdxOrderModel.setStrType(type == ConstantHolder.Constant.BOOKTYPE ? "解读版" : "小课");
                    wwdxOrderModel.setProductName(wwdxBookService.getByBookId(productId).getBookname());
                    break;
                case ConstantHolder.Constant.VIRTUALTYPE:
                    wwdxOrderModel.setStrType("阅读币");
                    wwdxOrderModel.setProductName("阅读币");
                    break;
                case ConstantHolder.Constant.VIPTYPE:
                    wwdxOrderModel.setStrType("会员");
                    wwdxOrderModel.setProductName("会员");
                    break;
                default:
                    break;
            }
        }
        return orderModels;
    }

    @Override
    public List<Object> bookshelfList(String unionid){
        List<Object> objects = Lists.newArrayListWithExpectedSize(16);
        //已购买
        objects.addAll(hashOperations.values(String.format(ConstantHolder.USER_PURCHASE_MAP,unionid)));
        //书架
        objects.addAll(hashOperations.values(String.format(ConstantHolder.USER_BOOKSHELF_MAP,unionid)));
        return objects;
    }

    @Override
    public Integer isorder(Long productid, String unionid){
        String key = String.format(ConstantHolder.USER_PURCHASE_MAP,unionid);
        Boolean hexists = hashOperations.hasKey(key, productid.toString());
        if (hexists != null && hexists){
            return 1;
        }
        return 0;
    }

    @Override
    public Integer isbookshelf(Long productid,String unionid){
        String key = String.format(ConstantHolder.USER_BOOKSHELF_MAP,unionid);
        Boolean hexists = hashOperations.hasKey(key, productid.toString());
        if (hexists != null && hexists){
            return 1;
        }
        return 0;
    }

    @Override
    public void purchase(String unionId,Long productId,Integer type){
        logger.info("用户:{} 购买的产品:{}",unionId,productId);
        PurchaseCordDTO purchaseCordDTO = new PurchaseCordDTO();
        switch (type){
            //主题
            case ConstantHolder.Constant.THEMETYPE:
                WwdxThemeModel wwdxThemeModel = wwdxThemeService.getByThemeId(productId);
                String[] bookList = wwdxThemeModel.getBook_list().split(",");
                purchaseCordDTO.setThemename(wwdxThemeModel.getTitle());
                purchaseCordDTO.setThemeimg(wwdxThemeModel.getImg());
                purchaseCordDTO.setThemebigimg(wwdxThemeModel.getBigimg());
                purchaseCordDTO.setContentabstract(wwdxThemeModel.getContentabstract());
                purchaseCordDTO.setBook_count(bookList.length);
                purchaseCordDTO.setType("0");
                break;
            //书籍 | 小课
            case ConstantHolder.Constant.BOOKTYPE:
            case ConstantHolder.Constant.SMALLBOOKTYPE:
                WwdxBookModel wwdxBookModel = wwdxBookService.getByBookId(productId);
                purchaseCordDTO.setBookid(wwdxBookModel.getBookid().toString());
                purchaseCordDTO.setReadingimg(wwdxBookModel.getBookimg());
                purchaseCordDTO.setReadingname(wwdxBookModel.getBookname());
                purchaseCordDTO.setBookrecommend(wwdxBookModel.getBookrecommend());
                purchaseCordDTO.setVideoduration(wwdxBookModel.getVideoduration());
                purchaseCordDTO.setVideoauthorid(wwdxBookModel.getVideoauthorid());
                purchaseCordDTO.setCopywriter(wwdxBookModel.getCopywriter());
                purchaseCordDTO.setBookchapter_list(wwdxBookChapterService.findBookChapterList(productId));
                purchaseCordDTO.setType(type == ConstantHolder.Constant.BOOKTYPE ? "1" : "2");
                break;
            default:
                return;
        }
        purchaseCordDTO.setIsorder(1);
        purchaseCordDTO.setThemeid(productId.toString());
        purchaseCordDTO.setIndate(new DateTime().toString(ConstantHolder.Constant.LOCAL_DATE_TIME_PATTERN));
        //写入redis
        String key = String.format(ConstantHolder.USER_PURCHASE_MAP,unionId);
        hashOperations.put(key,productId.toString(),purchaseCordDTO);
    }

    @Override
    public WwdxOrderModel getByOrderNo(String orderno) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        params.put("orderno", orderno);
        return this.getByHql("from WwdxOrderModel where orderno=:orderno", params);
    }

    @Override
    public MerchantProductStatisticsDTO getMerchantProductDTO(String merchantId,Long productId,Date date) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        params.put("merchant_id",merchantId);
        params.put("product_id",productId);
        params.put("date",date);
        String sql = "select ifnull(sum(price),0) as total,IFNULL(COUNT(DISTINCT unionid),0) as count\n" +
                "from wwdx_order where merchant_id=:merchant_id and product_id=:product_id and status =1 AND TO_DAYS(create_time) = TO_DAYS(:date)\n" +
                "and unionid NOT IN (SELECT unionid FROM wwdx_personal WHERE white = 1)";
        Map map = (Map) this.findBySql(sql, params).get(0);
        return new MerchantProductStatisticsDTO((BigDecimal) map.get("total"),((BigInteger) map.get("count")).longValue());
    }
}